package cc.rengu.igas.share.core.service.trans;

import cc.rengu.igas.channel.wechat.facade.request.FinancialTransMsgPushRequest;
import cc.rengu.igas.channel.wechat.facade.response.FinancialTransMsgPushResponse;
import cc.rengu.igas.share.common.constant.ShareServiceConstant;
import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.igas.share.common.util.GlobalEsbUtil;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.igas.smps.facade.base.Header;
import cc.rengu.igas.smps.facade.request.GeneralSmsNoticeRequest;
import cc.rengu.igas.smps.facade.response.GeneralSmsNoticeResponse;
import cc.rengu.igas.smps.facade.result.Result;
import cc.rengu.oltp.service.base.DubboAsynBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.MchntOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.TxnNoticeInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.MchntOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.TxnNoticeInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.entity.TxnNoticeInfo;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.common.enums.TransTypeEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.TxnInfo;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.TxnInfoService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.service.realize.impl.TxnInfoServiceImpl;
import cc.rengu.oltp.utility.annotation.BIZ_PROCESS;
import cc.rengu.oltp.utility.util.DateUtil;
import cc.rengu.oltp.utility.util.GlobalTransUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;

import java.util.ArrayList;
import java.util.List;

public class TransSmsNoticeService extends DubboAsynBaseService {
    @BIZ_PROCESS
    public void proceWechatNoticeResult() throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        TxnInfo txnInfo = (TxnInfo) xmlTreeUtil.getXmlTreeObjectValue(TreeNodeConstant.TXN_INFO,TxnInfo.class);
        FinancialTransMsgPushRequest financialTransMsgPushRequest = (FinancialTransMsgPushRequest) xmlTreeUtil.getXmlTreeObjectValue(TreeNodeConstant.DUBBO_REQUEST,FinancialTransMsgPushRequest.class);
        MchntOrderInfo mchntOrderInfo = (MchntOrderInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.MCHNT_ORDER_INFO);
        String responseStr = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.DUBBO_RESPONSE);
        Result<FinancialTransMsgPushResponse> result = JSON.parseObject(responseStr, new TypeReference<Result<FinancialTransMsgPushResponse>>(){});
        String instId = financialTransMsgPushRequest.getHeader().getInstId();
        TxnNoticeInfoMapper txnNoticeInfoMapper = new TxnNoticeInfoMapperImpl();
        /* 微信公众号推送失败，发送短信给商户联系人 */
        MchntService mchntService = new MchntServiceImpl();
        if (null == result || !result.isSuccess() || !OltpRpcdEnum.TRANS_SUCCESS.getRespCode().equals(result.getResult().getRespCode())) {
            /* 获取短信发送开送配置 */
            SysParamService sysParamService = new SysParamServiceImpl();
            SysParam sysParam = sysParamService.getSysParamInfo(instId, "SMS_SWITCH_PARAM", "SMS_SEND_FLAG");
            if (null != sysParam && AppParamConstant.YES.equals(sysParam.getParamValue().trim())) {
                /* 获取商户基本信息 */
                MchntInfo mchntInfo = mchntService.getMchntInfo(mchntOrderInfo.getInstId(), mchntOrderInfo.getMchntNo());
                if (null != mchntInfo && AppParamConstant.YES.equals(mchntInfo.getSmsSendFlag())) {
                    /* 检查是否已发送过短信 */
                    TxnNoticeInfo txnNoticeInfo = txnNoticeInfoMapper.selectTxnNoticeInfoByPrimaryKey(instId, mchntOrderInfo.getSysSeqNum(), mchntOrderInfo.getMchntNo(), "01", mchntInfo.getContactPhone());
                    if (null == txnNoticeInfo) {
                        DubboService dubboService = new DubboServiceImpl();
                        GeneralSmsNoticeRequest generalSMSNoticeRequest = initSmsNoticeMsg(financialTransMsgPushRequest, mchntInfo, mchntOrderInfo, txnInfo);
                        if (null != generalSMSNoticeRequest) {
                            Result<GeneralSmsNoticeResponse> smsResult = (Result<GeneralSmsNoticeResponse>) dubboService.callDubboService(ShareServiceConstant.SMS_PLAT_SEND_SERVICE, ShareServiceConstant.SMS_PLAT_SEND_METHOD, generalSMSNoticeRequest);
                            if (null == smsResult || !smsResult.isSuccess() || !OltpRpcdEnum.TRANS_SUCCESS.getRespCode().equals(smsResult.getResult().getRespCode())) {
                                rglog.error("调用短信平台发送短信通知失败:{}", JSON.toJSONString(generalSMSNoticeRequest));
                            }
                            /* 登记短信发送记录 */
                            txnNoticeInfo = initTxnNoticeInfo(mchntOrderInfo, txnInfo, "01", mchntInfo.getContactPhone(), generalSMSNoticeRequest.getSmsContent());
                            txnNoticeInfo.setNoticeStaus("01");
                            int iReturnCode = txnNoticeInfoMapper.insertTxnNoticeInfo(txnNoticeInfo);
                            if (0 != iReturnCode) {
                                rglog.warn("登记短信通知信息失败:{},iReturnCode:<{}>", JSON.toJSONString(txnNoticeInfo), iReturnCode);
                            }
                        }
                    }
                }
            }
            /* 获取微信公众号推送记录 */
            TxnNoticeInfo txnNoticeInfo = txnNoticeInfoMapper.selectTxnNoticeInfoByPrimaryKey(instId, mchntOrderInfo.getSysSeqNum(), mchntOrderInfo.getMchntNo(), "00", financialTransMsgPushRequest.getOpenId());
            if (null == txnNoticeInfo) {
                /* 登记微信公众号发送记录 */
                txnNoticeInfo = initTxnNoticeInfo(mchntOrderInfo, txnInfo, "00", financialTransMsgPushRequest.getOpenId(), JSON.toJSONString(financialTransMsgPushRequest));
                txnNoticeInfo.setNoticeStaus("02");
                int iReturnCode = txnNoticeInfoMapper.insertTxnNoticeInfo(txnNoticeInfo);
                if (0 != iReturnCode) {
                    rglog.warn("登记微信公众号通知信息失败:{},iReturnCode:<{}>", JSON.toJSONString(txnNoticeInfo), iReturnCode);
                }
            } else {
                txnNoticeInfo.setTryMaxTimes(txnNoticeInfo.getTryTimes() + 1);
                txnNoticeInfo.setLastNoticeTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
                int iReturnCode = txnNoticeInfoMapper.updateTxnNoticeInfoByPrimaryKey(txnNoticeInfo);
                if (0 != iReturnCode) {
                    rglog.warn("更新微信公众号通知信息失败,iReturnCode:<{}>", iReturnCode);
                }
            }
            rglog.warn("微信公众号消息推送失败,mchntNo:{},openId:{},orderAmt:{}", mchntOrderInfo.getMchntNo(), financialTransMsgPushRequest.getOpenId(), mchntOrderInfo.getOrderAmt());
            throw new BizException(OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR);
        }
    }

    /**
     * 生成发送短信内容
     *
     * @param financialTransMsgPushRequest 交易推送信息
     * @param mchntInfo                    商户信息
     * @param mchntOrderInfo               商户订单信息
     * @param txnInfo                      交易信息
     * @return 短信消费对象
     * @throws Exception 异常
     */
    private GeneralSmsNoticeRequest initSmsNoticeMsg(FinancialTransMsgPushRequest financialTransMsgPushRequest, MchntInfo mchntInfo, MchntOrderInfo mchntOrderInfo, TxnInfo txnInfo) throws Exception {
        GeneralSmsNoticeRequest generalSMSNoticeRequest = new GeneralSmsNoticeRequest();
        Header header = new Header();
        header.setVersion(financialTransMsgPushRequest.getHeader().getVersion());
        header.setTransDate(financialTransMsgPushRequest.getHeader().getTransDate());
        header.setTransTime(financialTransMsgPushRequest.getHeader().getTransTime());
        header.setTxnNum("00450000000E01");
        header.setBizType(AppParamConstant.DEFAULT_BIZ_TYPE);
        header.setInstId(financialTransMsgPushRequest.getHeader().getInstId());
        header.setSrcSysId(AppParamConstant.SYS_ID);
        header.setChanlId(AppParamConstant.SYS_ID);
        header.setTraceNo(GlobalEsbUtil.generateEsbSeqeuenceNumber(financialTransMsgPushRequest.getHeader().getInstId()));
        generalSMSNoticeRequest.setHeader(header);
        generalSMSNoticeRequest.setRealtimeFlag("1");
        generalSMSNoticeRequest.setAppointTime("0");
        List<String> phoneNoList = new ArrayList<>();
        phoneNoList.add(mchntInfo.getContactPhone());
        generalSMSNoticeRequest.setPhoneList(phoneNoList);
        generalSMSNoticeRequest.setTemplateId("S01");
        /* 拼装短信内容 */
        if (TransTypeEnum.PAY.equals(TransTypeEnum.getTransType(txnInfo.getSrcTxnAuthCfg().getTxnNum()))) {
            String msgContent = "(辅助通知)尊敬的用户您于" + mchntOrderInfo.getTxnTime() +
                    "发生" + txnInfo.getSrcTxnAuthCfg().getTxnName() +
                    "交易" + mchntOrderInfo.getRealSettleAmt() + "元，" +
                    "订单:" + mchntOrderInfo.getMchntOrderId();
            generalSMSNoticeRequest.setSmsContent(msgContent);
        } else if (TransTypeEnum.REFUND.equals(TransTypeEnum.getTransType(txnInfo.getSrcTxnAuthCfg().getTxnNum()))) {
            String msgContent = "(辅助通知)尊敬的用户您于" + mchntOrderInfo.getTxnTime() +
                    "发生" + txnInfo.getSrcTxnAuthCfg().getTxnName() +
                    "交易" + mchntOrderInfo.getRealSettleAmt() + "元";
            MchntOrderInfoMapper mchntOrderInfoMapper = new MchntOrderInfoMapperImpl();
            List<MchntOrderInfo> mchntOrderInfoList = mchntOrderInfoMapper.selectMchntOrderInfoBySysSeqNum(mchntOrderInfo.getInstId(), mchntOrderInfo.getOrigSysSeqNum());
            if (null != mchntOrderInfoList && !mchntOrderInfoList.isEmpty()) {
                msgContent += "，原订单:" + mchntOrderInfoList.get(0).getMchntOrderId();
            }
            generalSMSNoticeRequest.setSmsContent(msgContent);
        } else {
            rglog.info("非支付或者退款交易，不发送短信!");
            return null;
        }
        return generalSMSNoticeRequest;
    }

    /**
     * 初始化消息推送信息
     *
     * @param mchntOrderInfo 商户订单信息
     * @param txnInfo        交易信息
     * @param noticeType     通知类型（00-公众号推送、01-短信推送、02-手机银行推送、03-语音设备推送）
     * @param noticeTarget   通知对象
     * @param noticeMsg      通知内容
     * @return 交易通知信息表中信息
     */
    private TxnNoticeInfo initTxnNoticeInfo(MchntOrderInfo mchntOrderInfo, TxnInfo txnInfo, String noticeType, String noticeTarget, String noticeMsg) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        /* 登记微信公众号消息推送失败记录 */
        TxnNoticeInfo txnNoticeInfo = new TxnNoticeInfo();
        txnNoticeInfo.setInstId(mchntOrderInfo.getInstId());
        txnNoticeInfo.setSysSeqNum(mchntOrderInfo.getSysSeqNum());
        txnNoticeInfo.setMchntNo(mchntOrderInfo.getMchntNo());
        txnNoticeInfo.setNoticeType(noticeType);
        txnNoticeInfo.setNoticeTarget(noticeTarget);
        txnNoticeInfo.setMchntOrderId(mchntOrderInfo.getMchntOrderId());
        txnNoticeInfo.setMsgSrcId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SRC_SYS_ID));
        txnNoticeInfo.setTransChannelId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_CHANNEL_ID));
        txnNoticeInfo.setTxnNum(txnInfo.getSrcTxnAuthCfg().getTxnNum());
        txnNoticeInfo.setBizType(txnInfo.getSrcTxnAuthCfg().getBizType());
        txnNoticeInfo.setTxnDate(mchntOrderInfo.getTxnDate());
        txnNoticeInfo.setTxnTime(mchntOrderInfo.getTxnTime());
        txnNoticeInfo.setOrderAmt(mchntOrderInfo.getOrderAmt());
        txnNoticeInfo.setTryMaxTimes(3);
        txnNoticeInfo.setTryTimes(1);
        txnNoticeInfo.setNoticeMsg(noticeMsg);
        txnNoticeInfo.setNoticeTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        return txnNoticeInfo;
    }
}
